package projectbs.cmd;

import java.util.concurrent.Executor;
import java.util.concurrent.Executors;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.lmax.disruptor.BlockingWaitStrategy;
import com.lmax.disruptor.EventFactory;
import com.lmax.disruptor.EventHandler;
import com.lmax.disruptor.EventTranslatorOneArg;
import com.lmax.disruptor.dsl.Disruptor;
import com.lmax.disruptor.dsl.ProducerType;
import common.socket.packet.Packet;

public class CommandFactory {

	static Logger logger = LoggerFactory.getLogger(CommandFactory.class);

	private static final CommandFactory instance;
	static {
		instance = new CommandFactory();
	}
	public static final int RING_BUFFER_SIZE = 16;

	final Disruptor<PacketEvent> disruptor;

	final EventFactory<PacketEvent> eventFactory = new EventFactory<PacketEvent>() {
		@Override
		public PacketEvent newInstance() {
			return new PacketEvent();
		}
	};

	final EventHandler<PacketEvent> packetProcessor = new EventHandler<PacketEvent>() {

		@Override
		public void onEvent(PacketEvent event, long sequence, boolean endOfBatch)
				throws Exception {
			execute(event.getPacket());
		}
	};

	final EventTranslatorOneArg<PacketEvent, Packet> eventTranslator = new EventTranslatorOneArg<PacketEvent, Packet>() {

		@Override
		public void translateTo(PacketEvent event, long sequence, Packet packet) {
			event.setPacket(packet);
		}
	};

	@SuppressWarnings("unchecked")
	private CommandFactory() {
		Executor executor = Executors.newFixedThreadPool(Runtime.getRuntime()
				.availableProcessors());
		disruptor = new Disruptor<PacketEvent>(eventFactory, RING_BUFFER_SIZE,
				executor, ProducerType.SINGLE, new BlockingWaitStrategy());

		disruptor.handleEventsWith(packetProcessor);
		disruptor.start();
	}

	public void publish(Packet packet) {
		disruptor.publishEvent(this.eventTranslator, packet);
	}

	private void execute(Packet packet) {
		// TODO
		String str = new String(packet.getByte());
		logger.error("receive client packet: {}", str);
	}

	public static CommandFactory getInstance() {
		return instance;
	}
}
